package com.ld.shieldsb.es.config;

import java.util.Arrays;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.ld.shieldsb.common.core.util.StringUtils;

@ConditionalOnProperty(prefix = "es", name = "enabled", havingValue = "true", matchIfMissing = false)
@Configuration
public class ElasticConfig {

    /**
     * 单机
     */
    @Value("${es.host:}")
    public String host;

    @Value("${es.port:0}")
    public int port;

    @Value("${es.scheme:}")
    public String scheme;

    @Value("${es.username:}")
    public String username;

    @Value("${es.password:}")
    public String password;

    /**
     * 集群，逗号分隔多地址
     */
    @Value("${es.urls:#{null}}")
    public String[] urls;
    /**
     * 集群账号密码，username@password
     */
    @Value("${es.credentials:}")
    public String credentials;

    private HttpHost makeHttpHost() {
        return new HttpHost(host, port, scheme);
    }

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        if (ObjectUtils.isNotEmpty(urls)) { // 集群
            // 创建多个HttpHost
            HttpHost[] httpHosts = Arrays.stream(urls).map(HttpHost::create).toArray(HttpHost[]::new);
            RestClientBuilder builder = RestClient.builder(httpHosts);

            if (StringUtils.isNotEmpty(credentials)) { // 需要验证
                CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                String cusername = null;
                String cpassword = null;
                final int pwdIdx = credentials.indexOf('@'); // 密码中可能存在@符号，所以不是用split
                if (pwdIdx > 0) {
                    cusername = credentials.substring(0, pwdIdx); // 不包含pwdIdx
                    cpassword = credentials.substring(pwdIdx + 1);
                }
                credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(cusername, cpassword));
                builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
                // 完整写法如下：
                /*builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
                        return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                });*/
            }

            return new RestHighLevelClient(builder);
        } else { // 单机
            RestClientBuilder builder = RestClient.builder(makeHttpHost());

            if (StringUtils.isNotEmpty(username)) { // 需要验证
                CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
                builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
                // 完整写法如下：
                /*builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
                        return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                });*/
            }
            return new RestHighLevelClient(builder);
        }

    }
}
